package com.appspot.yozmcup.util;

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.SecretKeySpec;

public class Encryption {
	public static String getEncryptStr(String password) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException{
		Key key = generateKey("AES", password); 
		String transformation = "AES/ECB/PKCS5Padding"; 
		Cipher cipher = Cipher.getInstance(transformation); 
		cipher.init(Cipher.ENCRYPT_MODE, key); 
		byte[] plain = password.getBytes(); 
		byte[] encrypt = cipher.doFinal(plain); 
		return toHexString(encrypt);
	}
	
	public static Key generateKey(String algorithm, String keyStr) throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException {
		byte[] keyStrBytes = keyStr.getBytes(); 
		int len = keyStrBytes.length; 
		byte[] keyData = new byte[16]; 
		if (len >= 16) { 
			System.arraycopy(keyStrBytes, 0, keyData, 0, 16); 
		} else { 
			System.arraycopy(keyStrBytes, 0, keyData, 0, len); 
			for (int i = 0; i < (16 - len); i++) { 
				keyData[len + i] = keyStrBytes[i % len]; 
			} 
		} 
		
	    String upper = algorithm.toUpperCase();
	    if ("DES".equals(upper)) {
	        KeySpec keySpec = new DESKeySpec(keyData);
	        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(algorithm);
	        SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
	        return secretKey;
	    } else if ("DESede".equals(upper) || "TripleDES".equals(upper)) {
	        KeySpec keySpec = new DESedeKeySpec(keyData);
	        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(algorithm);
	        SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
	        return secretKey;
	    } else {
	        SecretKeySpec keySpec = new SecretKeySpec(keyData, algorithm);
	        return keySpec;
	    }
	}
	
	public static String toHexString(byte[] bytes) {
		if (bytes == null) {
			return null;
		}
		StringBuffer result = new StringBuffer();
		for (byte b : bytes) {
			result.append(Integer.toString((b & 0xF0) >> 4, 16));
			result.append(Integer.toString(b & 0x0F, 16));
		}
		return result.toString();
	}
	
	public static String toHexString(byte b) {
		StringBuffer result = new StringBuffer(3);
		result.append(Integer.toString((b & 0xF0) >> 4, 16));
		result.append(Integer.toString(b & 0x0F, 16));
		return result.toString();
	}
	
	public static byte[] toBytes(String digits, int radix) throws IllegalArgumentException, NumberFormatException {
		if (digits == null) {
			return null;
		}
		if (radix != 16 && radix != 10 && radix != 8) {
			throw new IllegalArgumentException("For input radix: \"" + radix + "\"");
		}
		int divLen = (radix == 16) ? 2 : 3;
    	int length = digits.length();
    	if (length % divLen == 1) {
    		throw new IllegalArgumentException("For input string: \"" + digits + "\"");
    	}
    	length = length / divLen;
    	byte[] bytes = new byte[length];
    	for (int i = 0; i < length; i++) {
    		int index = i * divLen;
    		bytes[i] = (byte)(Short.parseShort(digits.substring(index, index+divLen), radix));
    	}
    	return bytes;
	}
	
}
